﻿using System;
using System.Drawing;
using System.Media;
using System.Windows.Forms;
using CloudShot.Entities;
using CloudShot.Interfaces;
using CloudShot.Properties;
using CloudShot.Utils;
using CloudShot.Utils.Drawings;

namespace CloudShot
{
	internal class ShotCapturer : ICapturer
	{
		private readonly string _activeStorageName;
		private readonly bool _enableSounds;
		private readonly Color _fillColor;

		public ShotCapturer(string activeStorageName, bool enableSounds, Color fillColor)
		{
			_activeStorageName = activeStorageName;
			_enableSounds = enableSounds;
			_fillColor = fillColor;
		}

		public Image Capture()
		{
			Rectangle screenSize = GetScreenSize();
			Bitmap backgroundImage = ScreenCapture.CaptureRectangle(screenSize);

			//When you are shotting menus, sometimes focus stayed on menu. 
			//This call will close menu and set focus to current window.
			//SendKeys.SendWait("{Esc}");  //closes menu	

			using (var shotForm = new ShotForm(_activeStorageName, _fillColor))
			{
				shotForm.Location = screenSize.Location;
				shotForm.Size = screenSize.Size;
				shotForm.BackgroundImage = backgroundImage; //this code must be here, you must set beckground before form takes focus

				if (shotForm.ShowDialog() != DialogResult.OK || shotForm.CaptureInfo == null)
					return null;

				if (_enableSounds)
					PlayShotSound();

				CaptureInfo captureInfo = shotForm.CaptureInfo;
				var labelFont = new Font(shotForm.Font.FontFamily, 11f, FontStyle.Regular);// TODO: remove, use shared fornt here and in ShotState
				Image result = GetImage(backgroundImage, captureInfo, labelFont);

				shotForm.BackgroundImage = null;
				backgroundImage.Dispose();

				return result;
			}
		}

		private static void PlayShotSound()
		{
			using (var player = new SoundPlayer(Resources.CAMERA))
			{
				player.Play();
			}
		}

		#region Utils

		private static Rectangle GetScreenSize()
		{
			int left = 0;
			int top = 0;
			int right = 0;
			int bottom = 0;

			//при фотографировании окон надо учитывать что координаты на primary screen могут быть отрицательными (Y = -124)
			//http://dl.dropbox.com/u/145751/%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%20%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D1%8F%D1%8E%D1%82%D1%81%D1%8F%20%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D1%8B%20%D0%BE%D0%BA%D0%BD%D0%B0%20%D0%BF%D1%80%D0%B8%20%D1%82%D0%B0%D0%BA%D0%BE%D0%BC%20%D1%81%D0%BC%D0%B5%D1%89%D0%B5%D0%BD%D0%B8%D0%B8.png

			foreach (Screen screen in Screen.AllScreens)
			{
				left = Math.Min(left, screen.Bounds.Left);
				top = Math.Min(top, screen.Bounds.Top);
				right = Math.Max(right, screen.Bounds.Right);
				bottom = Math.Max(bottom, screen.Bounds.Bottom);
			}
			
			return new Rectangle(left, top, right - left, bottom - top);
		}

		protected virtual Image GetImage(Bitmap backgroundImage, CaptureInfo captureInfo, Font labelFont)
		{
			var rect = captureInfo.ClientBounds;

			if (rect.Width <= 0 || rect.Height <= 0 || rect.X < 0 || rect.Y < 0)
				return null;

			Bitmap bmpCrop = backgroundImage.Clone(rect, backgroundImage.PixelFormat);
			bmpCrop.DrawLabelOverImage(captureInfo.LabelText, labelFont);
			return bmpCrop;
		}

		#endregion
	}
}